import { observer } from 'mobx-react-lite';
import { memo, useState, useMemo } from 'react';
import { useMemoizedFn } from 'ahooks';

import Sender from '@/view/home/component/Sender';
import MessageHistory from '@/view/home/component/MessageHistory';
import { MessageHistoryList } from '@/view/home/component/MessageHistory/type';
import Welcome from '@/view/home/component/Welcome';
import ResumeDetail from '@/view/home/component/ResumeDetail';

import { WindowListener } from '@/type';
import useIpcListen from '@/hooks/useIpcListen';
import useEventSource from '@/hooks/useEventSource';
import { GET_ANSWER } from '@/request/sse/question';

interface AnswerResult {
    result: string;
    done: boolean;
    tools: boolean;
}

export const Home = memo(
    observer(() => {
        const [thinking, setThinking] = useState(false);
        const [messageHistory, setMessageHistory] =
            useState<MessageHistoryList>([]);

        const getAnswer = useEventSource(GET_ANSWER);
        const ipcListen = useIpcListen();
        ipcListen(WindowListener.ready, (_: unknown, value: string) => {
            console.log('app start is success...', value);
        });

        // 是否显示欢迎界面
        const showThinkingStep = useMemo(
            () => messageHistory?.length,
            [messageHistory]
        );

        // 回复问题
        const answerQuestion = (answer: AnswerResult) => {
            setMessageHistory((history) => {
                const newHistory = [...history];
                const { result, tools } = answer;
                const lastHistoryItem = newHistory.at(-1);
                if (lastHistoryItem) {
                    if (tools) {
                        lastHistoryItem.id = Date.now();
                        lastHistoryItem.value = result;
                    } else {
                        newHistory.pop();
                        newHistory.push({
                            id: Date.now(),
                            type: 'robot',
                            value: result,
                            status: 'text'
                        });
                    }
                }
                return newHistory;
            });
        };

        // 问题 loading 效果
        const loadingAnswer = (question: string) => {
            const id = Date.now();
            setThinking(true);
            const messages: typeof messageHistory = [
                {
                    id,
                    type: 'user',
                    value: question
                },
                {
                    id: id + 1,
                    type: 'robot',
                    value: '',
                    status: 'loading',
                    question
                }
            ];
            setMessageHistory(messageHistory.concat(messages));
        };

        // 问题异常效果
        const errorAnswer = () => {
            setMessageHistory((history) => {
                const newHistory = [...history];
                const lastHistoryItem = newHistory.at(-1);
                if (lastHistoryItem) {
                    lastHistoryItem.status = 'error';
                }
                return newHistory;
            });
            setThinking(false);
        };

        // answer 返回 sse 实例
        const requestAnswer = useMemoizedFn(async (question: string) => {
            loadingAnswer(question);
            const close = getAnswer({ question }, (event, error) => {
                if (error) errorAnswer();
                if (event?.data) {
                    const responseData = JSON.parse(event.data);
                    if (responseData.done) {
                        setThinking(false);
                        close();
                    } else {
                        answerQuestion(responseData);
                    }
                }
            });
        });

        // 重试问题
        const retryQuestion = useMemoizedFn((question: string) => {
            if (thinking) return;
            requestAnswer(question);
        });

        return (
            <section className="w-[100vw] h-[calc(100%-110px)]">
                <section className="relative py-0 flex flex-col h-full">
                    <section
                        className={`flex items-center justify-center min-h-[65vh] px-[15%] ${showThinkingStep ? 'flex-1 overflow-y-auto' : ''}`}
                    >
                        {showThinkingStep ? (
                            <MessageHistory
                                retry={retryQuestion}
                                history={messageHistory}
                            />
                        ) : (
                            <Welcome />
                        )}
                    </section>
                    <Sender thinking={thinking} requestAnswer={requestAnswer} />
                </section>

                <ResumeDetail />
            </section>
        );
    })
);
